﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.IO.IsolatedStorage;
using iRemoteComputing.Phone.Labb1;
using Microsoft.Phone.Notification;
using System.Collections.ObjectModel;
using System.IO;

namespace iRemoteComputing.Phone.Pages
{
    public partial class MainPage : PhoneApplicationPage
    {
        List<Calcs> ongoingCalcs = new List<Calcs>();
        List<Calcs> finishedCalcs = new List<Calcs>();
        IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;

        //Data members for this class
        //A unique ID for your phone, saved to internal memory
        Guid deviceID;

        //Add a reference to your deployed Push Service URL and name it ServiceReference1
        //and this line will compile. In Solution Explorer, Right-click References,
        //then click "Add Service Reference," then enter the URL for the SVC file
        //for the Push Service and click "Go." Verify that the
        //Push Service's four methods are indeed exposed then click "OK."
        ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();

        //URI for this app's notification channel.
        HttpNotificationChannel myPushChannel;

        public MainPage()
        {
            InitializeComponent();
            List<Calcs> calcs = new List<Calcs>();

            if (!settings.Contains("savedCalcs"))
            {
                settings.Add("savedCalcs", calcs);
                settings.Save();
            }
            else
            {
                calcs = (List<Calcs>) settings["savedCalcs"];
            }

            foreach (Calcs calc in calcs)
            {
                if (calc.finished == true)
                {
                    finishedCalcs.Add(calc);
                }
                else
                {
                    ongoingCalcs.Add(calc);
                }
            }

            this.listBox1.ItemsSource = finishedCalcs;
            this.listBox2.ItemsSource = ongoingCalcs;



            //First, generate a GUID on this phone and save it; reuse if it exists to
            //keep consistent with service's data.
            if (IsolatedStorageSettings.ApplicationSettings.Contains("DeviceId"))
            {
                //load existing
                deviceID = (Guid)IsolatedStorageSettings.ApplicationSettings["DeviceId"];
            }
            else
            {
                //generate new ID
                deviceID = Guid.NewGuid();
                IsolatedStorageSettings.ApplicationSettings["DeviceId"] = deviceID;
            }
            //Next, create a notification channel which will have its own URI that the
            //web service will need to know. We're naming the channel for this
            //app "myChannel." Channels need only be created once per app;
            //if the URI ever changes, the ChannelUriUpdated event will fire. This
            //event also fires when the channel is created for the first time.
            myPushChannel = HttpNotificationChannel.Find("myChannel");
            //check to see if this channel has already been created; if so, reuse
            if (myPushChannel == null)
            {
                //rawmessage.Text += " Channel was null.";
                //This channel needs to be created. ChannelUriUpdated will fire upon completion.
                myPushChannel = new HttpNotificationChannel("myChannel"); //create, then attach delegates, then Open()
                attachHandlerFunctions();
                myPushChannel.Open(); // will not fire ChannelUriUpdated if no handler is wired up first!
            }
            else
            {
                //rawmessage.Text += " Channel was found!";
                //ChannelUriUpdated is not going to fire. Call subscribing method on
                //web service. Attach delegates.
                attachHandlerFunctions();
                client.SubscribeMyPhoneAsync(deviceID, myPushChannel.ChannelUri.ToString());
            }
        }

        private void NewCalc_Click(object sender, RoutedEventArgs e)
        {
            this.NavigationService.Navigate(new Uri("/Pages/MakeRoute.xaml", UriKind.Relative));
        }

        void attachHandlerFunctions()
        {
            //attaches delegates to push channel events
            //if error, print onscreen
            myPushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(myPushChannel_ErrorOccurred);
            //After call to SubscribeMyPhone completes, notify of success
            client.SubscribeMyPhoneCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_SubscribeMyPhoneCompleted);
            //ChannelUriUpdated fires when channel is first created or the channel URI changes
            myPushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(myPushChannel_ChannelUriUpdated);
            //Handle raw push notifications, which are received only while app is running.
            myPushChannel.HttpNotificationReceived += new EventHandler<HttpNotificationEventArgs>(myPushChannel_HttpNotificationReceived);
        }
        void myPushChannel_HttpNotificationReceived(object sender, HttpNotificationEventArgs e)
        {
            //Fires from shell thread, so updates to UI have to use dispatcher's
            //BeginInvoke() method. The body of the notification is a stream,
            //per the MPNS standard, but we know it's just text per our web
            //service design, so here we just decode, and display.
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                //this will fire in UI thread
                StreamReader myReader = new StreamReader(e.Notification.Body);
                //rawmessage.Text = "Received Raw Notification: " + myReader.ReadToEnd();
            });
        }
        void myPushChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
        {
            //also fires in notification thread. There are a couple things we want to do
            //here, once we know we have a valid channel from MPNS.
            // 1) Make sure phone's shell knows this channel is authorized to receive Tile
            //updates when app is not running.
            if (myPushChannel.IsShellTileBound == false)
            {
                var ListOfAllowedDomains = new Collection<Uri> {
                //Lists domains that can send tile updates and so forth as push notifications.
                //Only these authorized domains will be allowed by the shell to
                //push new tiles to the phone
                new Uri(@"http://localhost:10214")
                //new Uri(@"http://localhost:10214")
                //e.g. if you published a webservice at http://foo.com/service1.svc -- put "http://foo.com" here.
                };
                //Register this channel with the shell, pass on authorized
                //domain in way method expects
                myPushChannel.BindToShellTile(ListOfAllowedDomains);
            }
            //2) Make sure phone's shell knows this channel is authorized to receive
            //Toast messages when app is not running
            if (myPushChannel.IsShellToastBound == false)
            {
                myPushChannel.BindToShellToast();
            }
            //3) Show that this event fired onscreen.
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                //rawmessage.Text = "uri updated";
            });
            //4) Pass the new ChannelUri on to the subscription service.
            client.SubscribeMyPhoneAsync(deviceID, e.ChannelUri.ToString());
        }

        void client_SubscribeMyPhoneCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            //Handles completion of call to SubscribeMyPhone() on web service
            if (e.Error == null)
            {
                // no server-side error occurred
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    //subscriptionStatus.Text = "Subscribed!";
                });
            }
            else
            {
                //show error onscreen
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    //subscriptionStatus.Text = e.Error.Message;
                });
            }
            //As a last step, since we know at this point that we will have
            //a valid ChannelUri, print its value onscreen. Don't do this in real
            //life, obviously. Here, it's just to show how MPNS works.
            //channelURITextBlock.Text = myPushChannel.ChannelUri.ToString();
        }
        void myPushChannel_ErrorOccurred(object sender, NotificationChannelErrorEventArgs e)
        {
            //handles channel error caused from indirect exception
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                //subscriptionStatus.Text = e.Message;
            });
        }

        private void CalcSelected_Click(object sender, RoutedEventArgs e)
        {
            Button bt = (Button)sender;
            string id = bt.Tag.ToString();
            string uri = "/Pages/BrowsePage.xaml?id=" + id;

            NavigationService.Navigate(
                new Uri(uri, UriKind.Relative)
                );
        }
    }
}